#region

using COSXML;
using COSXML.Auth;
using COSXML.Model.Object;
using Microsoft.Extensions.Options;
using Vin.Extension.Framework.Upload.Options;
using Vin.Extension.Framework.Upload.Tencent.Options;
using Vin.Tool.AspNetCore.Service;
using Vin.Tool.Core.PathCategory;
using Vin.Tool.Domain.ExceptionModel;

#endregion

namespace Vin.Extension.Framework.Upload.Tencent.Service;

public class TencentCosService : VinBaseService
{
    private readonly IOptionsMonitor<CosOption> _cosOption;
    private readonly IOptionsMonitor<UploadOption> _uploadOption;
    private CosXml _cosXml;

    private string? Bucket => _cosOption.CurrentValue.Bucket;
    private string Host => _uploadOption.CurrentValue.Host ?? "";

    public TencentCosService(IOptionsMonitor<CosOption> cosOption, IOptionsMonitor<UploadOption> uploadOption)
    {
        _cosOption = cosOption;
        _uploadOption = uploadOption;
        var option = cosOption.CurrentValue;
        if (!option.IsValidate)
        {
            throw new BusinessException("请检查腾讯云COS配置是否正确");
        }

        _cosXml = new CosXmlServer(new CosXmlConfig.Builder()
                .SetRegion(option.Region)
                .Build(),
            new DefaultQCloudCredentialProvider(option.SecretId,
                option.SecretKey, option.DurationSecond));
    }

    public string Upload(string dir, string extension, Stream data)
    {
        return Upload(GenerateDirPath(dir, extension), data);
    }

    public string Upload(string dir, string extension, byte[] data)
    {
        return Upload(GenerateDirPath(dir, extension), new MemoryStream(data));
    }

    // ------------------------------------ 私有方法 ------------------------------------

    /// <summary>
    /// 上传文件（Stream）
    /// </summary>
    private string Upload(string path, Stream data)
    {
        try
        {
            // 发起上传
            var result = _cosXml.PutObject(ChangeRequest(new PutObjectRequest(Bucket, path, data)));
            if (result.httpCode == 200)
            {
                return Path.Join(Host, path);
            }
        }
        catch (System.Exception e)
        {
            throw new BusinessException(e.Message);
        }

        throw new BusinessException("上传失败");
    }

    /// <summary>
    /// 生成文件路径
    /// </summary>
    private string GenerateDirPath(string dir, string extension)
    {
        dir = PathTool.DirPathCheck(dir);
        extension = PathTool.ExtensionCheck(extension);
        // dir = dir.StartsWith("/") ? dir : "/" + dir;
        // dir = dir.EndsWith("/") ? dir : dir + "/";
        // extension = extension.StartsWith(".") ? extension : "." + extension;
        return Path.Join(dir, Guid.NewGuid().ToString("N") + extension);
    }

    /// <summary>
    /// 修改请求
    /// </summary>
    private PutObjectRequest ChangeRequest(PutObjectRequest request)
    {
        if (_cosOption.CurrentValue.Download)
        {
            request.SetRequestHeader("Content-Disposition", "attachment");
        }
        else
        {
            request.SetRequestHeader("Content-Disposition", "inline");
        }

        return request;
    }
}